using UnityEngine;
using System.Collections;

/// \class  gkAbyssalGiantCamera
/// \brief  The abyssal giant camera Controller
[AddComponentMenu("GK/Engine/GameCore/Camera/gkVolumeCamera")]
public class gkVolumeCamera : MonoBehaviour
{
	/// The volume
	public GameObject Volume;
	
    /// Game volume camera direction
    public Vector3 VolumeCameraAimDirection = new Vector3(0.0f, 0.0f, 1.0f);
	
    /// Game volume camera up direction
    public Vector3 VolumeCameraUpDirection = new Vector3(0.0f, 1.0f, 0.0f);
	
	/// Focus plane offset
	public float FocusPlaneOffsetPercent;
	
    /// The camera owner
    private Camera m_rCameraComponent;

    /// \brief  Called just after the game begin to play
    void Start()
    {
        //Grab the owner as a camera
        m_rCameraComponent = GetComponent<Camera>();

        // Setup the camera
        UpdateCamera();
    }

    /// \brief  Update the camera to see all the game volume
    void UpdateCamera()
    {
        float fTanFov;
        float fVolumeHalfHeightX;
        float fVolumeHalfHeightY;
        float fCameraDistanceFromVolume;
        Bounds oVolumeBoudingBox;
        Vector3 f3VolumeBoudingBoxPosition;
        Vector3 f3VolumeCameraLocation;
        float fVolumeCameraAspectRatio;

        // Get the bounding box of the game volume
        gkUtilityBounds.GrabColliderOrRendererBounds(Volume, out oVolumeBoudingBox);

        // Compute the game volume position
        f3VolumeBoudingBoxPosition = oVolumeBoudingBox.center;

        // Take the closest face of the volume
        f3VolumeBoudingBoxPosition.z = oVolumeBoudingBox.min.z + FocusPlaneOffsetPercent * oVolumeBoudingBox.size.z;

        // Compute the half height in the X direction
        fVolumeHalfHeightX = 0.5f * (oVolumeBoudingBox.max.x - oVolumeBoudingBox.min.x);

        // Compute the half height in the Y direction
        fVolumeHalfHeightY = 0.5f * (oVolumeBoudingBox.max.y - oVolumeBoudingBox.min.y);

        // Compute the tangent
        fTanFov = Mathf.Tan(Mathf.Deg2Rad * m_rCameraComponent.fieldOfView * 0.5f);

        // If the tangent is null we put the camera the farthest we can
        if (fTanFov == 0.0f)
        {
            // TEMP_SEV : use clipping FarPlane
            fCameraDistanceFromVolume = 100000.0f;
        }
        else
        {
            // Else we make sure the camera look exactly at the main plane
            // of the game volume

            // Use the X direction to compute the camera distance 
            // based on the ratio : tangent(FovY) = HalfHeightY / Distance
            fCameraDistanceFromVolume = fVolumeHalfHeightY / fTanFov;
        }

        // Compute the camera location based on the direction and the distance
        f3VolumeCameraLocation = f3VolumeBoudingBoxPosition
            - fCameraDistanceFromVolume * VolumeCameraAimDirection;

        // Compute the aspect ratio based on the game volume width/height ratio
        if (fVolumeHalfHeightY == 0.0f)
        {
            fVolumeCameraAspectRatio = 4.0f / 3.0f;
        }
        else
        {
            fVolumeCameraAspectRatio = fVolumeHalfHeightX / fVolumeHalfHeightY;
        }

        // Update camera data
        transform.position = f3VolumeCameraLocation;
        transform.LookAt(VolumeCameraAimDirection, VolumeCameraUpDirection);
        m_rCameraComponent.nearClipPlane = oVolumeBoudingBox.min.z - transform.position.z;
        m_rCameraComponent.farClipPlane = oVolumeBoudingBox.max.z - transform.position.z;
        m_rCameraComponent.aspect = fVolumeCameraAspectRatio;
		m_rCameraComponent.orthographicSize = fVolumeHalfHeightY;
    }
}
